"use strict";
const code = require("../errorCode.js");

module.exports = (options) => {
  return async (ctx, next) => {
    const db = ctx.params['db']
    const name = ctx.params['name']
    
    if (!options.whitelist.some((item) => item == ctx.request.url)) {
      const user = ctx.request.header.user || {id:null,organ:null,role:null};
      let authList = []
      let role = ctx.app.getUserCache('user-'+user.id)
      if (role.length==0) {
        //TODO: 正式使用打开，调试注释
        // ctx.body = ctx.app.error(code.USER_LOGOUT,'用户已注销或未登录');
        // return
        //TODO: 调试模式打开，正式使用注释
        const auth = await ctx.service.mysql.excute('meta','authByRoleName',{role:user.role.join("','")});
        ctx.app.setUserCache('user-'+user.id,user.role,auth.result.rows);
        authList = auth.result.rows
        role = ctx.app.getUserCache('user-'+user.id);
        //----------------------------------------------------
      }else{
        authList = role.auth
      }
      let isAuth = false
      for(let i=0;i<options.operations.length;i++){
        if (ctx.url.indexOf(options.operations[i].path)==0){
          for(let j=0;j<authList.length;j++){
            //数据库操作的权限控制
            if (authList[j].db_name == db && authList[j].table_name == name && authList[j].auth.substring(options.operations[i].pointer,options.operations[i].pointer+1)=='1'){
              let operation = {...getOperation(authList[j].auth,options.operations)}
              operation['columns'] = authList[j].columns ? authList[j].columns.split(',') : []
              ctx.request.header.operation = operation
            }
            //公用操作的权限控制，例如发送mq消息、文件的上传下载等
            if(authList[j].auth.substring(options.operations[i].pointer,options.operations[i].pointer+1)=='1' && options.public.indexOf(options.operations[i].auth)>=0){
              let operation = {...getOperation(authList[j].auth,options.operations)}
              ctx.request.header.operation = operation
            }
          }
        }
      }
      console.log(`[${ctx.url}] 用户权限:`,role)
      if (!isAuth){
        if (role.hasOwnProperty('role')){
          if (Array.isArray(role.role)){
            if (role.role.indexOf('ADMIN')>=0){
              let operation = {
                SELECT:true,
                DELETE:true,
                INSERT:true,
                UPDATE:true,
                TREE:true,
                EXCUTE:true,
                UPLOAD:true,
                DOWNLOAD:true,
                PREVIEW:true,
                MS_SEND:true,
                columns:["*"],
              }
              ctx.request.header.operation = operation
              console.log(`[${ctx.url}] 操作权限:`,ctx.request.header.operation)
              await next()
            }
          }else{
            ctx.body = ctx.app.error(code.AUTH,'权限不足')
            return
          }
        }else{
          if (Array.isArray(role)){
            if (role.indexOf('ADMIN')>=0){
              let operation = {
                SELECT:true,
                DELETE:true,
                INSERT:true,
                UPDATE:true,
                TREE:true,
                EXCUTE:true,
                UPLOAD:true,
                DOWNLOAD:true,
                PREVIEW:true,
                MS_SEND:true,
                columns:["*"],
              }
              ctx.request.header.operation = operation
              console.log(`[${ctx.url}] 操作权限:`,ctx.request.header.operation)
              await next()
            }
          }else{
            ctx.body = ctx.app.error(code.AUTH,'权限不足')
            return
          }
        }
        
      }else{
        console.log(`[${ctx.url}] 操作权限:`,ctx.request.header.operation)
        await next()
      }
    }
  };
};

function getOperation(auth,operations){
  let operation = {}
  for (let i=0;i<operations.length;i++){
    if(auth.substring(operations[i].pointer,operations[i].pointer+1)=='1'){
      operation[operations[i].auth]=true
    }else{
      operation[operations[i].auth]=false
    }
  }
  return operation
}
